/*
 * Created on 2005-9-13
 *
 */
package com.hd123.rumba.log;

import java.io.FileReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.StringTokenizer;

import com.hd123.rumba.runtime.FormatSettings;

/**
 * 访问量统计
 * 
 * @author caili
 */
public class VisitingStatistic {

  public static void main(String args[]) throws Exception {
    VisitingStatistic vs = new VisitingStatistic();
    List vsr = vs.collect("C:/je/jakarta/jakarta-tomcat-5.5.7/logs/tango.log");
    vs.printvsr(System.out, vsr);
  }

  public static class VSResult {
    public String action;
    public int count = 0;
    public float minResponse = 0;
    public float maxResponse = 0;
    public float response = 0;
  }

  /**
   * 从file中统计com.hd123.tango.TIME的记录 <br>
   * 
   * @param ins
   * @return list of VSResult
   * @throws Exception
   */
  public List collect(String file) throws Exception {
    final String mark = "com.hd123.tango.TIME - perf";
    Hashtable h = new Hashtable();
    LineNumberReader in = new LineNumberReader(new FileReader(file));
    Date minDate = null, maxDate = null;
    while (true) {
      String line = in.readLine();
      if (line == null)
        break;
      if (line.indexOf(mark) == -1)
        continue;
      try {
        StringTokenizer st = new StringTokenizer(line, "|");
        // 0-0-19=date
        String token = st.nextToken();
        Date date = FormatSettings.SDFyMdHms.parse(token.substring(0, 19));
        if (minDate == null || minDate.after(date))
          minDate = date;
        if (maxDate == null || maxDate.before(date))
          maxDate = date;
        // 1-response time
        token = st.nextToken();
        int responseTime = Integer.parseInt(token);
        // 2-ip addr
        token = st.nextToken();
        // 3-action
        token = st.nextToken();
        String action = token;
        // 4-sessionId

        // do statistics
        VSResult r = (VSResult) h.get(action);
        if (r == null) {
          r = new VSResult();
          r.action = action;
          h.put(action, r);
        }
        if (r.minResponse > responseTime || r.minResponse == 0)
          r.minResponse = responseTime;
        if (r.maxResponse < responseTime || r.maxResponse == 0)
          r.maxResponse = responseTime;
        r.response = (r.response * r.count + responseTime) / (r.count + 1);
        r.count++;
      } catch (Exception e) {
        ;
      }
    }
    in.close();
    ArrayList list = new ArrayList();
    Enumeration e = h.keys();
    VSResult r ;
    while (e.hasMoreElements()) {
      String key = (String) e.nextElement();
      r = (VSResult) h.get(key);
      list.add(r);
    }
    r = new VSResult();
    r.action = FormatSettings.SDFyMdHms.format(minDate) + "到" + FormatSettings.SDFyMdHms.format(maxDate);
    list.add(0, r);
    return list;
  }

  public void printvsr(PrintStream ps, List list) throws Exception {
    if (list.size() == 0) {
      ps.println("nothing found.");
      return;
    }
    ps.println("访问次数, 平均响应时间, 最小响应时间, 最大响应时间, 动作");
    for (int i = 0; i < list.size(); ++i) {
      VSResult r = (VSResult) list.get(i);
      ps.println(r.count + "," + (int) r.response + "," + (int) r.minResponse + "," + (int) r.maxResponse
          + "," + r.action);
    }
  }

  public void printvsr(OutputStream os, List list) throws Exception {
    try {
      if (list.size() == 0) {
        os.write("没有找到日志记录. 请检查log4j.properties的内容.\n".getBytes());
        return;
      }
      os.write("访问次数, 平均响应时间, 最小响应时间, 最大响应时间, 动作\n".getBytes());
      for (int i = 0; i < list.size(); ++i) {
        VSResult r = (VSResult) list.get(i);
        os.write((r.count + "," + (int) r.response + "," + (int) r.minResponse + "," + (int) r.maxResponse
            + "," + r.action + "\n").getBytes());
      }
    } finally {
      os.close();
    }
  }
}
